"use strict";
const path = require("path");
const defaultSettings = require("./src/settings.js");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
  .BundleAnalyzerPlugin;
function resolve(dir) {
  return path.join(__dirname, dir);
}
const webpack = require("webpack");
// 代码压缩
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
// gzip压缩
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg|ico)(\?.*)?$/i;
const IS_PROD = ["production", "prod", "staging", "stage"].includes(
  process.env.NODE_ENV
);
// console.log('process.env.NODE_ENV :>> ', process.env.NODE_ENV);
const name = defaultSettings.title; // page title

// If your port is set to 80,
// use administrator privileges to execute the command line.
// For example, Mac: sudo npm run
// You can change the port by the following methods:
// port = 9528 npm run dev OR npm run dev --port = 9528
const port = process.env.port || process.env.npm_config_port || 8080; // dev port

// All configuration item explanations can be find in https://cli.vuejs.org/config/
module.exports = {
  css: {
    sourceMap: false,
    modules: false,
    // requireModuleExtension: false,
    // 解决开发环境style无法触发热更新问题
    extract: IS_PROD
      ? {
          ignoreOrder: true
        }
      : false
  },
  /**
   * You will need to set publicPath if you plan to deploy your site under a sub path,
   * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
   * then publicPath should be set to "/bar/".
   * In most cases please use '/' !!!
   * Detail: https://cli.vuejs.org/config/#publicpath
   */
  publicPath: "/",
  outputDir: "dist",
  assetsDir: "static",
  lintOnSave: false,
  productionSourceMap: false,
  devServer: {
    port: port,
    open: true,
    overlay: {
      warnings: false,
      errors: true
    },
    proxy: {
      "/siddhi/*": {
        // search为转发路径
        target: process.env.VUE_APP_SIDDHI_URL, // 目标地址
        changeOrigin: true,
        ws: true,
        secure: false,
        pathRewrite: {
          "^/siddhi": ""
        },
        headers: {
          referer: process.env.VUE_APP_SIDDHI_URL,
          origin: process.env.VUE_APP_SIDDHI_URL
        }
      },

      "/edge/*": {
        target: process.env.VUE_APP_IOTBACK_URL, // 目标地址
        changeOrigin: true,
        ws: true,
        secure: false,
        pathRewrite: {
          "^/edge": "edge"
        },
        headers: {
          referer: process.env.VUE_APP_IOTBACK_URL,
          origin: process.env.VUE_APP_IOTBACK_URL
        }
      },

      "/socket_siddhi/*": {
        target: process.env.VUE_APP_SIDDHI_WS_URL, // 目标地址
        changeOrigin: true,
        ws: true,
        secure: false,
        pathRewrite: {
          "^/socket_siddhi": ""
        },
        headers: {
          referer: process.env.VUE_APP_SIDDHI_WS_URL,
          origin: process.env.VUE_APP_SIDDHI_WS_URL
        }
      }
    }
    // 应该是模拟数据的东西(此处会妨碍post请求的跨域配置)
    // before: require('./mock/mock-server.js')
  },
  configureWebpack: {
    // provide the app's title in webpack's name field, so that
    // it can be accessed in index.html to inject the correct title.
    name: name,
    // devtool: "source-map",
    // devtool: "#eval-source-map",
    devtool: "cheap-module-source-map",
    resolve: {
      alias: {
        "@": resolve("src"),
        "@public": resolve("public")
      }
    }
  },
  configureWebpack: config => {
    if (IS_PROD) {
      const plugins = [
        // new BundleAnalyzerPlugin({ analyzerPort: 9099 }),
        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
      ];
      plugins.push(
        new CompressionWebpackPlugin({
          filename: "[path].gz[query]",
          algorithm: "gzip",
          test: productionGzipExtensions,
          threshold: 10240,
          minRatio: 0.8
          // deleteOriginalAssets: true //是否删除原资源
        })
      );
      config["performance"] = {
        //打包文件大小配置
        maxEntrypointSize: 10000000,
        maxAssetSize: 30000000
      };
      config.plugins = [...config.plugins, ...plugins];
      config.resolve.alias = {
        "@": resolve("src"),
        "@public": resolve("public")
      };
    }
  },
  chainWebpack(config) {
    // it can improve the speed of the first screen, it is recommended to turn on preload
    config.plugin("preload").tap(() => [
      {
        rel: "preload",
        // to ignore runtime.js
        // https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
        fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
        include: "initial"
      }
    ]);

    // when there are many pages, it will cause too many meaningless requests
    config.plugins.delete("prefetch");
    // set svg-sprite-loader
    config.module
      .rule("svg")
      .exclude.add(resolve("src/icons"))
      .end();
    config.module
      .rule("icons")
      .test(/\.svg$/)
      .include.add(resolve("src/icons"))
      .end()
      .use("svg-sprite-loader")
      .loader("svg-sprite-loader")
      .options({
        symbolId: "icon-[name]"
      })
      .end();

    config.when(process.env.NODE_ENV !== "development", config => {
      config
        .plugin("ScriptExtHtmlWebpackPlugin")
        .after("html")
        .use("script-ext-html-webpack-plugin", [
          {
            // `runtime` must same as runtimeChunk name. default is `runtime`
            inline: /runtime\..*\.js$/
          }
        ])
        .end();
      // config.optimization.splitChunks({
      //   chunks: "all",
      //   maxInitialRequests: Infinity,
      //   minSize: 300000, // 依赖包超过300000bit将被单独打包
      //   automaticNameDelimiter: "-",
      //   cacheGroups: {
      //     vendor: {
      //       test: /[\\/]node_modules[\\/]/,
      //       name(module) {
      //         const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
      //         return `chunk.${packageName.replace("@", "")}`;
      //       },
      //       priority: 10
      //     }
      //   }
      // });
      config.optimization.splitChunks({
        //在cacheGroups外层的属性设定适用于所有缓存组，不过每个缓存组内部可以重设这些属性
        chunks: "all", //将什么类型的代码块用于分割，三选一： "initial"：入口代码块 | "all"：全部 | "async"：按需加载的代码块
        // minSize: 300000, //大小超过30kb的模块才会被提取
        // maxSize: 0, //只是提示，可以被违反，会尽量将chunk分的比maxSize小，当设为0代表能分则分，分不了不会强制
        // minChunks: 1, //某个模块至少被多少代码块引用，才会被提取成新的chunk
        // maxAsyncRequests: 5, //分割后，按需加载的代码块最多允许的并行请求数，在webpack5里默认值变为6
        // maxInitialRequests: 3, //分割后，入口代码块最多允许的并行请求数，在webpack5里默认值变为4
        automaticNameDelimiter: "~", //代码块命名分割符
        // name: true, //每个缓存组打包得到的代码块的名称
        cacheGroups: {
          // 拆包处理
          // vendors: {
          //   name: 'chunk-vendors',
          //   test: /[\\/]node_modules[\\/]/,
          //   chunks: 'initial',
          //   priority: 1,
          //   reuseExistingChunk: true,
          //   enforce: false
          // },
          moment: {
            name: "chunk-moment", // split elementUI into a single package
            priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
            test: /[\\/]node_modules[\\/]_?moment(.*)/, // in order to adapt to cnpm

            chunks: "initial"
          },
          elementUI: {
            name: "chunk-elementUI", // split elementUI into a single package
            priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
            test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
            chunks: "initial"
          },
          echarts: {
            name: "chunk-echarts",
            priority: 20,
            test: /[\\/]node_modules[\\/]_?echarts(.*)/
          },
          vue2AceEditor: {
            name: "chunk-vue2-ace-editor",
            priority: 20,
            test: /[\\/]node_modules[\\/]_?vue2-ace-editor(.*)/,
            chunks: "all"
          },

          commons: {
            name: "chunk-commons",
            test: resolve("src/components"), // can customize your rules
            minChunks: 2, //  minimum common number
            priority: 20,
            reuseExistingChunk: true,
            chunks: "all"
          }
        }
      });
      // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
      config.optimization.runtimeChunk("single"),
        (config.optimization.minimizer = [
          new UglifyJsPlugin({
            uglifyOptions: {
              output: {
                // 删除注释
                comments: true
              },
              //生产环境自动删除console
              compress: {
                warnings: false, // 若打包错误，则注释这行
                drop_debugger: true, //清除 debugger 语句
                drop_console: true, //清除console语句
                pure_funcs: ["console.log"]
              }
            },
            sourceMap: false,
            parallel: true
          })
        ]);
    });
  },
  pluginOptions: {
    "style-resources-loader": {
      preProcessor: "less",
      patterns: [path.resolve(__dirname, "./src/assets/style/index.less")]
    }
  }
};
